package com.test.gl;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;

import com.google.android.utils.AdaptiveBackgroundTexture;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;

/**
* This class is an object representation of
* a Cube containing the vertex information,
* texture coordinates, the vertex indices
* and drawing functionality, which is called
* by the renderer.
*
* @author Savas Ziplies (nea/INsanityDesign)
*/
public class Quad {

    float maxU;
	float maxV;
   /** The buffer holding the vertices */
   private FloatBuffer vertexBuffer; // 定义图形的各顶点坐标
   /** The buffer holding the texture coordinates */
   private FloatBuffer textureBuffer;  //要绘制的元素
   /** The buffer holding the indices */
   private ByteBuffer indexBuffer; // 图形顶点的绘制顺序
   // 3D中各种图形都是靠三角形叠拼起来的，openGL基于triangle实现各种其他的图形。
   //所以，一个正方形是靠两个三角形拼起来的。
   
   public Bitmap[] bitmaps = new Bitmap[2];
   /**
    * The initial vertex definition
    *
    * Note that each face is defined, even
    * if indices are available, because
    * of the texturing we want to achieve
    * 顶点坐标，-1表示初始点，0表示屏幕中央，1表示屏幕的宽、长、高的顶点，都是比例。
    */   
    private float vertices[] = {
                   //Vertices according to faces
                   -1.0f, -1.0f, 1.0f, //Vertex 0， （-1，-1）左下角
                   1.0f, -1.0f, 1.0f,  //v1 (1,-1) 右下角
                   //-1.0f, 1.0f, 1.0f,  //v2  (-1,1)左上角
                   1.0f, 1.0f, 1.0f,   //v3  (1,1) 右上角
                   -1.0f, 1.0f, 1.0f,  //v2  (-1,1)左上角
                                 };
   
    /** The initial texture coordinates (u, v) */
    /*
     * 此数组定义了取原图中得哪部分来显示，这是一个比例, 从 0 到 1
     * Android 系统中纹理的坐标和android本身对 屏幕的坐标定义相同，为
     * 左上角是 (0,0), 右下角是 (1,1)
     * 而openGL是上下翻转的： 左下角(-1,-1), 右上角是 (1,1)
     * 
     * */
    private float texture[] = {          
                   //Mapping coordinates for the vertices
                   0.0f, 1.0f,
                   //0.0f, 1.0f,
                   1.0f, 1.0f,
                   1.0f, 0.0f,
                   0.0f, 0.0f,
                                  };
       
    /** The initial indices definition */   
    private byte indices[] = {
                   //Faces definition
                  // 0,1,3, 0,3,2,          //Face front
    		0,1,2, 0,2,3, 
                                  };// 绘制两个三角形，顶点顺序如示

   /**
    * The Quad constructor.
    *
    * Initiate the buffers.
    */
   public Quad() {
      //
      ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
      byteBuf.order(ByteOrder.nativeOrder());
      vertexBuffer = byteBuf.asFloatBuffer();
      vertexBuffer.put(vertices);
      vertexBuffer.position(0);

      //
      byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
      byteBuf.order(ByteOrder.nativeOrder());
      textureBuffer = byteBuf.asFloatBuffer();
      textureBuffer.put(texture);
      textureBuffer.position(0);

      //
      indexBuffer = ByteBuffer.allocateDirect(indices.length*2);
      indexBuffer.put(indices);
      indexBuffer.position(0);
   }

   /**
    * The object own drawing function.
    * Called from the renderer to redraw this instance
    * with possible changes in values.
    *
    * @param gl - The GL Context
    */
   public void draw(GL10 gl) {
	   drawMixed2D((GL11)gl,bitmaps[0],bitmaps[1],0,0,0,0.2f,720,1280);
   }
   
   
   /**
    * Load the textures
    *
    * @param gl - The GL Context
    * @param context - The Activity context
    */
   public void loadGLTexture(GL10 gl, Context context, Bitmap bmp) {
	   

      //Get the texture from the Android resource directory
      InputStream is = context.getResources().openRawResource(R.drawable.default_background);

      try {
         //BitmapFactory is an Android graphics utility for images
         bitmaps[0] = bmp;
         bitmaps[1] = BitmapFactory.decodeStream(is);
         //padding bitmap size to power of 2
         for(int i=0;i<2;++i){
	         bitmaps[i] = Bitmap.createScaledBitmap(bitmaps[i], 720, 1280, false);
	         int h = bitmaps[i].getHeight();
	         int w = bitmaps[i].getWidth();
	         int hi = pow2(h);
	         int wi = pow2(w);
	        
	         maxU = w/(float)wi;
	         maxV = h/(float)hi;
	       //Bitmap bb = load(bitmap);
	         bitmaps[i] = Bitmap.createScaledBitmap(bitmaps[i], wi, hi, false);
         }
         
      } finally {
         //Always clear and close
         try {
            is.close();
            is = null;
         } catch (IOException e) {
         }
      }
      
      bitmaps[0] = new AdaptiveBackgroundTexture(bitmaps[0]).load(null);
     
      bitmaps[1] = new AdaptiveBackgroundTexture(bitmaps[1]).load(null);
    

   }
   
   public void loadGLTexture(GL10 gl, Context context, int id) {
	   

	      //Get the texture from the Android resource directory
	      InputStream is = context.getResources().openRawResource(id);
	      InputStream is2 = context.getResources().openRawResource(R.drawable.default_background);

	      try {
	         //BitmapFactory is an Android graphics utility for images
	         bitmaps[0] = BitmapFactory.decodeStream(is);
	         bitmaps[1] = BitmapFactory.decodeStream(is2);
	         //padding bitmap size to power of 2
	         for(int i=0;i<2;++i){
		         bitmaps[i] = Bitmap.createScaledBitmap(bitmaps[i], 720, 1280, false);
		         int h = bitmaps[i].getHeight();
		         int w = bitmaps[i].getWidth();
		         int hi = pow2(h);
		         int wi = pow2(w);
		        
		         maxU = w/(float)wi;
		         maxV = h/(float)hi;
		       //Bitmap bb = load(bitmap);
		         bitmaps[i] = Bitmap.createScaledBitmap(bitmaps[i], wi, hi, false);
	         }
	         
	      } finally {
	         //Always clear and close
	         try {
	            is.close();
	            is2.close();
	            is = null;
	            is2= null;
	         } catch (IOException e) {
	         }
	      }
	      
	      bitmaps[0] = new AdaptiveBackgroundTexture(bitmaps[0]).load(null);
	     
	      bitmaps[1] = new AdaptiveBackgroundTexture(bitmaps[1]).load(null);
	    

	   }
   
   public void drawMixed2D(GL11 gl, Bitmap from, Bitmap to, float ratio, float x, float y, float z, float width, float height) {


       // Bind "from" and "to" to TEXTURE0 and TEXTURE1, respectively.
       if (bind(from, gl)) {
           gl.glActiveTexture(GL11.GL_TEXTURE1);

           if (bind(to, gl)) {
               // Enable TEXTURE1.
               gl.glEnable(GL11.GL_TEXTURE_2D);

               // Interpolate the RGB and alpha values between both textures.
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_COMBINE);
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_RGB, GL11.GL_INTERPOLATE);
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_COMBINE_ALPHA, GL11.GL_INTERPOLATE);

               // Specify the interpolation factor via the alpha component of
               // GL_TEXTURE_ENV_COLORes.
               final float[] color = { 1f, 1f, 1f, ratio };
               gl.glTexEnvfv(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_COLOR, color, 0);

               // Wire up the interpolation factor for RGB.
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_RGB, GL11.GL_CONSTANT);
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_RGB, GL11.GL_SRC_ALPHA);

               // Wire up the interpolation factor for alpha.
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_SRC2_ALPHA, GL11.GL_CONSTANT);
               gl.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_OPERAND2_ALPHA, GL11.GL_SRC_ALPHA);

               // Draw the combined texture.
               ((GL11Ext) gl).glDrawTexfOES(0, 0, 0, width, height);

               // Disable TEXTURE1.
               gl.glDisable(GL11.GL_TEXTURE_2D);
           }

           // Switch back to the default texture unit.
           gl.glActiveTexture(GL11.GL_TEXTURE0);
   //        mBoundTexture = null;
       }
   }
   
   public static int pow2(int size)
   	    {
    	        int small = (int)(Math.log((double)size)/Math.log(2.0f)) ;
   	        if ( (1 << small) >= size)
    	            return 1 << small;
    	        else 
    	            return 1 << (small + 1);
   	    } 
   
   
   
   public boolean bind(Bitmap bmp, GL11 gl){
	   Bitmap bitmap = bmp;

       if (bitmap != null) {
           final int width = bitmap.getWidth();
           final int height = bitmap.getHeight();
           int[] textureId = new int[1];
           // Define a vertically flipped crop rectangle for OES_draw_texture.
           int[] cropRect = { 0, height, width, -height };

           // Upload the bitmap to a new texture.
           gl.glGenTextures(1, textureId, 0);
           gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId[0]);
           gl.glTexParameteriv(GL11.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0);
           gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE);
           gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE);
           gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
           gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
           GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, bitmap, 0);
           return true;
       }
       return false;
   }
   
   
   
   
   
   
   
 //  
   
   
   
   
   
   
   //
   public static final Bitmap resizeBitmap(Bitmap bitmap, int maxSize) {
       int srcWidth = bitmap.getWidth();
       int srcHeight = bitmap.getHeight();
       int width = maxSize;
       int height = maxSize;
       boolean needsResize = false;
       if (srcWidth > srcHeight) {
           if (srcWidth > maxSize) {
               needsResize = true;
               height = ((maxSize * srcHeight) / srcWidth);
           }
       } else {
           if (srcHeight > maxSize) {
               needsResize = true;
               width = ((maxSize * srcWidth) / srcHeight);
           }
       }
       if (needsResize) {
           Bitmap retVal = Bitmap.createScaledBitmap(bitmap, width, height, true);
           return retVal;
       } else {
           return bitmap;
       }
   }
   
   

}

